/*
* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "plugin_manager/include/plugin.h"
#include "ai_interpreter.h"
#include "platform/dl_operation/include/infer_dl_operation.h"
#include "protocol/retcode_inner/infer_retcode_inner.h"
#include "utils/infer_macros.h"
#include "utils/log/infer_log.h"

namespace OHOS {
namespace AI_STD {
class HandleGuard {
public:
    HandleGuard(const std::string &aid, void *handle) : aid_(aid), handle_(handle)
    {
    }

    void Detach()
    {
        handle_ = nullptr;
    }

    ~HandleGuard()
    {
        CHK_RET_NONE(handle_ == nullptr);
        InferDlclose(handle_);
        handle_ = nullptr;
        HILOGI("[Plugin]Succeed to close library, aid=%s.", aid_.c_str());
    }
private:
    std::string aid_;
    void *handle_ = nullptr;
};

Plugin::Plugin(const std::string &aid, long long version, int frwk)
    : pluginAlgorithm_(nullptr), aid_(aid), version_(version), frwk_(frwk)
{
}

Plugin::~Plugin()
{
    int retcode = UnloadPluginAlgorithm();
    if (retcode != RETCODE_SUCCESS) {
        HILOGE("[Plugin]Failed to UnloadPluginAlgorithm. retcode=%d", retcode);
    } 
}

int Plugin::LoadPluginAlgorithm(const AlgorithmInfo &algoInfo)
{
    if (pluginAlgorithm_ != nullptr) {
        HILOGD("[Plugin]Algorithm has been loaded.");
        return RETCODE_SUCCESS;
    }
    //create instance of AIInterpreter for thirdparty inference framework
    pluginAlgorithm_ = new(std::nothrow)AIInterpreter(algoInfo);
    if (pluginAlgorithm_ == nullptr) {
        HILOGE("[Plugin]Failed to instance AIInterpreter.");
        return RETCODE_NULL_PARAM;
    }
    int retCode = pluginAlgorithm_->Load();
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[Plugin]Failed to load algorithm.");
        return retCode;
    }
    return RETCODE_SUCCESS;
}

int Plugin::UnloadPluginAlgorithm()
{
    if (pluginAlgorithm_ == nullptr) {
        HILOGD("[Plugin]Algorithm has been unloaded.");
        return RETCODE_SUCCESS;
    }
 
    int retCode = pluginAlgorithm_->Unload();
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[Plugin]Failed to unload algorithm.");
        return retCode;
    }
    
    AI_DELETE_INSTANCE(pluginAlgorithm_);
    HILOGI("[Plugin]Succeed to unload plugin algorithm, framework=%d., aid=%s.", frwk_, aid_.c_str());

    return RETCODE_SUCCESS;
}

AIInterpreter *Plugin::GetPluginAlgorithm()
{
    return pluginAlgorithm_;
}

void Plugin::SetPluginAlgorithm(AIInterpreter *pluginAlgorithm)
{
    pluginAlgorithm_ = pluginAlgorithm;
}

long long Plugin::GetVersion() const
{
    return version_;
}

std::string Plugin::GetAid() const
{
    return aid_;
}
int Plugin::GetFrwk() const
{
    return frwk_;
}

} // namespace AI_STD
} // namespace OHOS
